home *** CD-ROM | disk | FTP | other *** search
- Path: news.halcyon.com!usenet
- From: normanb@halcyon.com (Norm Bryar)
- Newsgroups: comp.lang.c++
- Subject: Re: Bizzare C++ bug...PLEASE CHECK IT OUT
- Date: Thu, 15 Feb 1996 17:17:54 GMT
- Organization: Northwest Nexus Inc.
- Message-ID: <4fvpr1$l27@news.halcyon.com>
- References: <4fsns9$8ga3@flute.aix.calpoly.edu>
- NNTP-Posting-Host: blv-pm10-ip5.halcyon.com
- X-Newsreader: Forte Free Agent 1.0.82
-
- Comments appended with <==
- --Norm
-
- mporcell@flute.aix.calpoly.edu (Michael Anthony Porcelli) wrote:
-
- >Hello all you helpful people. I was working on a project for school and I
- >ran into a super hard-to-find bug. Well, I found it and the project is
- >complete, but *where* the bug occured was what made it so hard to find and I
- >*still* don't understand why it occured when it did. Any input on this
- >would be appreciated. Thanks. Here it is:
-
- >struct A {
- > A(...);
- > ...
- > virtual ostream &Print(void) = 0; // r1
- > friend ostream &operator<<(ostream &os, const A &a) {return l.Print(os)}
- > //r2
- > ...
- >}
-
- Cool, I've never seen someone *define* <==
- a utility function within a struct or class <==
- and not have to use scope-resolution <==
- to access it. Must be 'cause of 'friend.' <==
-
- What does it mean to call I.Print(os) <==
- when the argument is a and A::Print <==
- takes no parameters? <==
-
- In MSVC4, if I defined operator<< as <==
- { return a.Print(os); } and declare Print to <==
- take an ostream parameter, then my <==
- linker would groan "unresolved external." <==
- I'd fix that by defining Print as follows <==
- virtual ostream & Print(ostream & os) = 0 <==
- { NULL; } <==
- Giving a pure-virtual a body is legal and <==
- makes the linker happy, even though <==
- at runtime I'd never expect A::Print() to <==
- get called. <==
- Could this help? <==
-
- >struct B : public A {
- > B(...);
- > ...
- >}
-
- >B::B(...) : A(...), ... { //r3
- > // ^
- > // Bug *occurs* here
- > ...
- > os << *this; //r4
- > // ^^
- > // Bug *is* here
- > ...
- >}
- >
- >struct C : public B {
- > ...
- > ostream &Print(void) const; //r5
- > ...
- >}
- >...
- >ostram &C::Print(void) {
- > ...
- >}
-
- >Well. I've tried to show in as much detail as I could exactly what was
- >going on. The bug was a compile time bug that produced the message:
-
- >Abort Process
-
- >Clearly the call to the overloaded operator<< (r2) at r4 will cause a crash
- >because it is a call from a base class constructor (B) to a virtual print
- >function (r1) that does not get defined until the derived class C (r5). The
- >reason that this bug was so darn hard to find is that it occured at r3 and
- >*not* at its location in the code (r4). I still have absolutely *no* idea
- >why this is so. It is perhaps a compiler dependant thing. If some of you
- >could compile and run my above code, maybe you could see if it occurs at the
- >same point in the code as it did for me. I am absolutely certain that it was
- >occuring where I indicated it was occuring (r3) because I spent hours on end
- >isolating it down to that exact spot. Any insight would be appreciated.
- >I'm using xlC on IBM AIX. I've also created a super simpified model of my
- >project with actual filled in C++ code that I could email you if you'd like
- >to take a look at it further.
-
- >You might be looking at this program that I wrote and be wondering why the
- >hell I'm doing this pure virtual print function and calling it in the base
- >class friend operator<< This is actually a very useful technique for
- >creating what amounts to a "virtual operator <<"
-
- >Thanks in advance,
-
- >-Mike
-
-
-
-